package cc.autoapi.pucong.auto.flow.core.flow.execNode.task.extend;


import cc.autoapi.pucong.auto.flow.core.flow.execNode.entity.node.ExecNode;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.entity.node.ExecParamIn;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.entity.node.NodeParamIn;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.entity.node.NodeParamOut;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.exception.AutoDesignException;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.selfenum.DataTypeEnum;
import cc.autoapi.pucong.auto.flow.core.flow.execNode.utils.DataValueUtils;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson2.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.util.*;

public class HttpTask extends AbstractExtendTask {

    private List<NodeParamIn> paramsIns;
    private List<NodeParamOut> paramsOuts;

    public HttpTask() {
        paramsIns = new ArrayList<>();
        NodeParamIn url = new NodeParamIn()
                .setParamCode("url")
                .setDateType(DataTypeEnum.STRING)
                .setDesc("请求地址，http://www.baidu.com")
                .setNeedValue(true);
        paramsIns.add(url);
        NodeParamIn methodType = new NodeParamIn()
                .setParamCode("methodType")
                .setDateType(DataTypeEnum.STRING)
                .setDesc("请求方法类型，例：POST、GET、DELETE、PUT")
                .setNeedValue(true);
        paramsIns.add(methodType);
        NodeParamIn contentType = new NodeParamIn()
                .setParamCode("contentType")
                .setDateType(DataTypeEnum.STRING)
                .setDesc("请求方法类型，例：application/json; charset=utf-8")
                .setNeedValue(true);
        paramsIns.add(contentType);
        NodeParamIn bodyParams = new NodeParamIn()
                .setParamCode("bodyParams")
                .setDateType(DataTypeEnum.MAP)
                .setNeedValue(false);
        paramsIns.add(bodyParams);
        NodeParamIn headerParams = new NodeParamIn()
                .setParamCode("headerParams")
                .setDateType(DataTypeEnum.MAP)
                .setNeedValue(false);
        paramsIns.add(headerParams);
        NodeParamIn queryParams = new NodeParamIn()
                .setParamCode("queryParams")
                .setDateType(DataTypeEnum.MAP)
                .setNeedValue(false);
        paramsIns.add(queryParams);

        paramsOuts = new ArrayList<>();
        NodeParamOut data = new NodeParamOut()
                .setParamCode("data")
                .setDesc("返回值")
                .setDateType(DataTypeEnum.STRING);
        paramsOuts.add(data);
        NodeParamOut status = new NodeParamOut()
                .setParamCode("status")
                .setDesc("接口调用状态")
                .setDateType(DataTypeEnum.NUMBER);
        paramsOuts.add(status);
    }

    @Override
    public void run() {
        ExecNode execNode = getExecNode();
        ExecParamIn urlParam = getParamInInfo("url");
        ExecParamIn methodTypeParam = getParamInInfo("methodType");
        ExecParamIn contentTypeParam = getParamInInfo("contentType");
        ExecParamIn queryParamsParam = getParamInInfo("queryParams");
        ExecParamIn headerParamsParam = getParamInInfo("headerParams");
        ExecParamIn bodyParamsParam = getParamInInfo("bodyParams");
        String url = urlParam.getDateValue().toString();
        String methodType = methodTypeParam.getDateValue().toString();
        String contentType = contentTypeParam.getDateValue().toString();

        Object dateValueQuery = queryParamsParam.getDateValue();
        String queryParams = "";
        if (dateValueQuery != null) {
            JSONObject jsonObject = (JSONObject) DataValueUtils.transDataType("queryParams", DataTypeEnum.MAP, dateValueQuery);
            queryParams = jsonObject.toJSONString();
        }

        Object dateValueHeader = headerParamsParam.getDateValue();
        String headerParams = "";
        if (dateValueHeader != null) {
            JSONObject jsonObject = (JSONObject) DataValueUtils.transDataType("headerParams", DataTypeEnum.MAP, dateValueHeader);
            headerParams = jsonObject.toJSONString();
        }

        Object dateValueBody = bodyParamsParam.getDateValue();
        String bodyParams = "";
        if (dateValueBody != null) {
            JSONObject jsonObject = (JSONObject) DataValueUtils.transDataType("bodyParams", DataTypeEnum.MAP, dateValueBody);
            bodyParams = jsonObject.toJSONString();
        }

        Map<String, String> headerMap = getMap2(headerParams);
        Map<String, Object> queryMap = getMap(queryParams);
        String urlWithParam = url;
        Set<Map.Entry<String, Object>> entries = queryMap.entrySet();
        if (entries.size() > 0) {
            if (!urlWithParam.contains("?")) {
                urlWithParam = url + "?";
            }
            for (Map.Entry<String, Object> entry : entries) {
                urlWithParam += entry.getKey() + "=" + entry.getValue() + "&";
            }
            if (!queryMap.isEmpty()) {
                urlWithParam = urlWithParam.substring(0, urlWithParam.length() - 1);
            }
        }
        HttpResponse response = null;
        if ("GET".equals(methodType)) {
            response = HttpRequest.get(urlWithParam)
                    .addHeaders(headerMap)
                    .contentType(contentType)
                    .execute();
        } else if ("POST".equals(methodType)) {
            response = HttpRequest.post(urlWithParam)
                    .addHeaders(headerMap)
                    .body(bodyParams)
                    .contentType(contentType)
                    .execute();
        } else if ("PUT".equals(methodType)) {
            response = HttpRequest.put(urlWithParam)
                    .addHeaders(headerMap)
                    .body(bodyParams)
                    .contentType(contentType)
                    .execute();
        } else if ("DELETE".equals(methodType)) {
            response = HttpRequest.delete(urlWithParam)
                    .addHeaders(headerMap)
                    .body(bodyParams)
                    .contentType(contentType)
                    .execute();
        } else {
            throw new AutoDesignException("API 请求类型设置错误，请重新检查url信息");
        }
        int status = response.getStatus();
        String res = response.body();
        setParamOutValue("status", status);
        setParamOutValue("data", res);
    }

    private Map<String, Object> getMap(String jsonString) {
        if (StringUtils.isBlank(jsonString)) {
            return new HashMap<>(16);
        }
        // 将JSON字符串转换为Map
        try {
            HashMap map = JSONObject.parseObject(jsonString, HashMap.class);
            return map;
        } catch (Exception e) {
            throw new AutoDesignException("HTTP接口，传入参数JSON格式错误，请检查");
        }
    }

    private Map<String, String> getMap2(String jsonString) {
        if (StringUtils.isBlank(jsonString)) {
            return new HashMap<>(16);
        }
        // 将JSON字符串转换为Map
        try {
            HashMap map = JSONObject.parseObject(jsonString, HashMap.class);
            return map;
        } catch (Exception e) {
            throw new AutoDesignException("HTTP接口，传入参数JSON格式错误，请检查");
        }
    }

    @Override
    public String getTaskName() {
        return "HTTP请求";
    }

    @Override
    public String getTaskDesc() {
        return null;
    }

    @Override
    public String getTaskSvgIcon() {
        return "<svg t=\"1728657575791\" class=\"icon\" viewBox=\"0 0 1490 1024\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\" p-id=\"11064\" width=\"32\" height=\"32\"><path d=\"M1203.118794 1023.767378a286.589732 286.589732 0 1 0 0-573.179463 302.407996 302.407996 0 0 0-46.524307 3.954566 390.80418 390.80418 0 0 0 2.093594-40.708769 413.833712 413.833712 0 0 0-827.667424 0 390.80418 390.80418 0 0 0 2.093593 40.708769 302.407996 302.407996 0 0 0-46.524307-3.954566 286.589732 286.589732 0 0 0 0 573.179463z\" fill=\"#4674CE\" p-id=\"11065\"></path><path d=\"M301.2451 610.39891v116.310767H442.911615v-116.310767h45.3612v277.28487H442.911615v-122.824171h-141.666515v122.824171H256.814387V610.39891zM747.413206 610.39891v38.847796h-90.722399v238.437074h-46.524308V649.246706h-90.722398v-38.847796zM986.315523 610.39891v38.847796h-90.955021v238.437074h-46.524307V649.246706h-89.791913v-38.847796zM1134.262819 610.39891c66.762381 0 100.492503 28.379827 100.492504 84.90686s-33.730123 85.837347-101.42299 85.837347h-69.786461v106.540663h-46.524307V610.39891z m-69.78646 131.89641h66.064516a74.438891 74.438891 0 0 0 44.198092-10.70059 43.732849 43.732849 0 0 0 13.957292-36.28896 41.639255 41.639255 0 0 0-14.422536-35.358473 71.647433 71.647433 0 0 0-43.732848-10.700591h-65.831895z\" fill=\"#FFFFFF\" p-id=\"11066\"></path></svg>";
    }

    @Override
    public List<NodeParamIn> getPropertyParamsIns() {
        return paramsIns;
    }

    @Override
    public List<NodeParamOut> getPropertyParamsOuts() {
        return paramsOuts;
    }
}
